
package com.niguang.work.show.common.util;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * HttpClientUtil
 *
 * @author
 */
public class HttpClientUtil {

    private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

    private static String UPLOAD = "http://47.106.194.24:9333/submit";
    private static String SELECT = "http://file.liuguohai.com";
    private static String UPDATE_DELETE = "http://47.106.194.24:9222";


    /**
     * 发送get请求
     *
     * @param url
     * @return
     */
    public static String get(String url) {
        return get(url, "application/x-www-form-urlencoded");
    }

    public static String get(String url, String contentType) {
        try {
            return Request.Get(url).setHeader("Content-Type", contentType)
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }

    public static String getByHeaderCity(String url, String city) {

        try {
            return Request.Get(url).setHeader("Content-Type", "application/x-www-form-urlencoded").setHeader("city", city)
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }


    /**
     * 发送post请求
     *
     * @param url    post url
     * @param params post参数
     * @return
     */
    public static String post(String url, Map<String, String> params) {
        try {
            List<NameValuePair> nvps = new ArrayList<>();
            params.forEach((key, value) -> nvps.add(new BasicNameValuePair(key, value)));
            return Request.Post(url)
                    .bodyForm(nvps)
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * 发送delete请求
     *
     * @param url 请求地址
     *            返回数据编码
     * @return String
     */
    public static String sendDelete(String url) {
        try {
            return Request.Delete(url)
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * post json数据
     *
     * @param url
     * @param jsonStr
     * @return
     */
    public static String postJson(String url, String jsonStr) {
        try {
            return Request.Post(url)
                    .bodyString(jsonStr, ContentType.APPLICATION_JSON)
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件读取（读取为二进制数组）
     *
     * @param url 文件地址
     * @return 文件的二进制数组
     */
    public static byte[] download(String url) {
        try {
            return Request.Get(url)
                    .execute().returnContent().asBytes();
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }


    public static String uploadFile(String url, String paramName, byte[] fileBytes, String fileName, ContentType contentType) {
        try {
            return Request.Post(url)
                    .body(
                            MultipartEntityBuilder.create()
                                    .addBinaryBody(paramName, fileBytes, contentType, fileName)
                                    .build()
                    )
                    .execute().returnContent().asString(StandardCharsets.UTF_8);
        } catch (IOException e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件上传
     *
     * @param collection
     * @param ttl        图片在小文件服务器上存活时间 eg:
     *                   3m: 3 minutes
     *                   4h: 4 hours
     *                   5d: 5 days
     *                   6w: 6 weeks
     *                   7M: 7 months
     *                   8y: 8 years
     * @return
     */
    public static String uploadFile(String collection, MultipartFile multipartFile, String ttl) {
        try {
            String contentType = multipartFile.getContentType();
            ContentType mimeType = ContentType.getByMimeType(contentType);
            if (mimeType == null) {
                mimeType = ContentType.create(contentType, "UTF-8");
            }
            String originalFilename = multipartFile.getOriginalFilename();
            String url = getUrl(collection, ttl);
            String s = Request.Post(url).body(
                    MultipartEntityBuilder.create()
                            .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                            .setCharset(Charset.forName("UTF-8"))
                            .addBinaryBody("file", multipartFile.getBytes(), mimeType, originalFilename)
                            .build()
            ).execute()
                    .returnContent()
                    .asString(Charset.forName("UTF-8"));
            ImageRes imageRes = JSON.parseObject(s, ImageRes.class);
            String fid = imageRes.getFid();
            String fileName = imageRes.getFileName();
            Integer size = imageRes.getSize();
            String fileUrl = imageRes.getFileUrl();
            if (StringUtils.isBlank(fid) || StringUtils.isBlank(fileName) || size == null || size == 0 || StringUtils.isBlank(fileUrl)) {
                log.error("上传文件出错，文件名：{},", fileName);
                return null;
            }
            return SELECT + fileUrl;
        } catch (Exception e) {
            log.error("上传文件出错,文件名：{},ttl:{}", multipartFile.getOriginalFilename(), ttl, e);
        }
        return "";
    }


    /**
     * 上传图片到服务器
     *
     * @param collection 集合
     * @param base64
     * @param ttl        存活时间
     * @return
     * @see HttpClientUtil#uploadFile
     */
    public static String uploadImage(String collection, String base64, String ttl) {
        if (StringUtils.isBlank(base64) || !StringUtils.startsWith(base64, "data:image/") || StringUtils.split(base64, ";").length != 2) {
            log.error("base64格式错误，base64:{}", base64);
        }
        final String type = base64.split(";")[0].split(":")[1];
        ContentType contentType = ContentType.getByMimeType(type);
        if (contentType == null) {
            contentType = ContentType.create(type);
        }
        final byte[] bytes = Base64Utils.decodeFromString(StringUtils.removeStart(base64.split(";")[1], "base64,"));
        String name = IdWorker.getIdStr() + "." + type.split("/")[1];
        getUrl(collection, ttl);
        String url = getUrl(collection, ttl);
        String s = null;
        try {
            s = Request
                    .Post(url)
                    .body(
                            MultipartEntityBuilder.create()
                                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                                    .setCharset(Charset.forName("UTF-8"))
                                    .addBinaryBody("file", bytes, contentType, name)
                                    .build()
                    ).execute()
                    .returnContent()
                    .asString(Charset.forName("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isBlank(s)) {
            return null;
        }
        ImageRes imageRes = JSON.parseObject(s, ImageRes.class);
        String fid = imageRes.getFid();
        String fileName = imageRes.getFileName();
        Integer size = imageRes.getSize();
        String fileUrl = imageRes.getFileUrl();
        if (StringUtils.isBlank(fid) || StringUtils.isBlank(fileName) || size == null || size == 0 || StringUtils.isBlank(fileUrl)) {
            log.error("上传文件出错，文件名：{},base64:{}", name, base64);
            return null;
        }
        return SELECT + fileUrl;
    }



    public static <T> String postXml(String url, T t) {
        XmlMapper xmlMapper = new XmlMapper();
        try {
            final String xmlStr = xmlMapper.writeValueAsString(t);
            return postXML(url,xmlStr);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String postXML(String url,String xml){
        CloseableHttpClient client = null;
        CloseableHttpResponse resp = null;
        try{
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");
            client = HttpClients.createDefault();
            StringEntity entityParams = new StringEntity(xml,"utf-8");
            httpPost.setEntity(entityParams);
            client = HttpClients.createDefault();
            resp = client.execute(httpPost);
            String resultMsg = EntityUtils.toString(resp.getEntity(),"utf-8");
            return resultMsg;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(client!=null){
                    client.close();
                }
                if(resp != null){
                    resp.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    public static String uploadImage(String collection, byte[] bytes, String ttl) {
        if (bytes == null) {
            log.error("图片不能为空");
        }
        String name = IdWorker.getIdStr() + ".jpg";
        String url = getUrl(collection, ttl);
        String s = null;
        try {
            s = Request
                    .Post(url)
                    .body(
                            MultipartEntityBuilder.create()
                                    .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                                    .setCharset(Charset.forName("UTF-8"))
                                    .addBinaryBody("file", bytes, ContentType.IMAGE_JPEG, name)
                                    .build()
                    ).execute()
                    .returnContent()
                    .asString(Charset.forName("UTF-8"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isBlank(s)) {
            return null;
        }
        ImageRes imageRes = JSON.parseObject(s, ImageRes.class);
        String fid = imageRes.getFid();
        String fileName = imageRes.getFileName();
        Integer size = imageRes.getSize();
        String fileUrl = imageRes.getFileUrl();
        if (StringUtils.isBlank(fid) || StringUtils.isBlank(fileName) || size == null || size == 0 || StringUtils.isBlank(fileUrl)) {
            log.error("byte上传文件出错，文件名：{}", name);
            return null;
        }
        return SELECT + fileUrl;
    }


    public static String getUrl(String collection, String ttl) {
        String url = UPLOAD;
        if (StringUtils.isNotBlank(ttl) && StringUtils.isNotBlank(collection)) {
            url = UPLOAD + "?ttl=" + ttl + "&collection=" + collection;
        } else if (StringUtils.isNotBlank(ttl)) {
            url = UPLOAD + "?ttl=" + ttl;
        } else if (StringUtils.isNotBlank(collection)) {
            url = UPLOAD + "?collection=" + collection;
        }
        return url;
    }


    /**
     * 判断某个链接是否存在
     *
     * @param url
     * @return
     */
    public static boolean isUrlOk(String url) {
        if (StringUtils.isBlank(url)) {
            return false;
        }
        try {
            return Request.Head(url).execute().returnResponse().getStatusLine().getStatusCode() == HttpStatus.SC_OK;
        } catch (Exception e) {
            log.error("调用httpClient出错，url:{}", url, e);
//            e.printStackTrace();
        }
        return false;
    }


    @Data
    public static class ImageRes {

        private String fid;

        private String fileName;

        private String fileUrl;

        private Integer size;

    }


}
